package cn.itsource.wechat.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.http.HttpUtil;
import cn.itsource.basic.config.exception.BusinessException;
import cn.itsource.basic.util.JsonResult;
import cn.itsource.basic.util.RedisService;
import cn.itsource.org.domain.User;
import cn.itsource.org.mapper.UserMapper;
import cn.itsource.org.pojo.loginInfo.LoginInfo;
import cn.itsource.org.pojo.vo.LoginVo;
import cn.itsource.wechat.domain.WxUser;
import cn.itsource.wechat.mapper.WxUserMapper;
import cn.itsource.wechat.pojo.dto.BindDto;
import cn.itsource.wechat.pojo.dto.WechartTokenDto;
import cn.itsource.wechat.pojo.dto.WechartUserInfoDto;
import cn.itsource.wechat.pojo.info.WeChatProperties;
import cn.itsource.wechat.service.IWeChatService;
import cn.itsource.wechat.service.IWxUserChatService;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

@Slf4j
@Service
public class WeChatServiceImpl implements IWeChatService {
    @Autowired
    private WeChatProperties weChatProperties;
    @Autowired
    private IWxUserChatService wxUserChatService;
    @Autowired
    private RedisService redisService;
    @Resource
    private UserMapper userMapper;
    @Resource
    private WxUserMapper wxUserMapper;
    @Override
    public String login() {
        //获取授权吗url
        String codeUrl = weChatProperties.getAuthorizationCodeUrl();
        log.info("codeUrl:{}",codeUrl);
        //    authorization-code-url: "https://open.weixin.qq.com/connect/qrconnect?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_login&state=%s#wechat_redirect"
        //注入
        String state = IdUtil.fastSimpleUUID();
        String format = String.format(codeUrl, weChatProperties.getAppId(), weChatProperties.getRedirectUri(), state);
        log.info("format:{}",format);
        return "redirect:"+format;
    }

    @Override
    public String callback(String code) {
        //----------------------------步骤2:根据code获取access_token------------------------------------------------
        //1.拿到获取token的url
        String tokenUrl = weChatProperties.getTokenUrl();
        //2.替换%s
        //    token-url: "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code"
        String tokenUrl1= String.format(tokenUrl, weChatProperties.getAppId(),weChatProperties.getAppSecrect(),code);
        //3.通过java代码调用这个url
        String tokenResult = HttpUtil.get(tokenUrl1);
        //result:{"access_token":"61_JoKprxxGFdw_G_O7LjFy0Ww_bOAaR7CEEbScWlgGcYLEHq4woKqnyHiUl-VaZJeyJOvFWPWMJ4RVg3ZVRI4rRL1QzeqAMDlvCm8tpfAm9N8","expires_in":7200,"refresh_token":"61_JNiO3Lfy9llU8ckkWTkZb_8RjdXivZzKwdzU0iYYQHZQWOcIlgFWGSaYnNN44L_aH8BQ9bwtqNNg6Ure2F3eKZaLByRBox9YjsZAb-CHDaM","openid":"oa9wA08wFUAASzeAjvcJupLXTVZg","scope":"snsapi_login","unionid":"ovnCWw9QMcFGNIK3bT11v6GhTCSc"}
        log.info("tokenResult:{}",tokenResult);
        //4.把json字符串转成对象WechartTokenDto
        WechartTokenDto wechartTokenDto = JSONObject.parseObject(tokenResult, WechartTokenDto.class);
        log.info("wechartTokenDto:{}",wechartTokenDto);
        //----------------------------步骤3,通过token拿到微信用户信息------------------------------------------------
        //1.拿到获取用户信息的url
      //  userinfo-url: "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s"
        String userInfoUrl = weChatProperties.getUserinfoUrl();
        //2.替换%s 并访问 //https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s"
        String userInfoResult = String.format(userInfoUrl, wechartTokenDto.getAccess_token(), weChatProperties.getAppId());
        String user = HttpUtil.get(userInfoResult);
        WechartUserInfoDto wechartUserInfoDto = JSONObject.parseObject(user, WechartUserInfoDto.class);
        log.info("wechartUserInfoDto:{}",wechartUserInfoDto);
        /**
         *  三种情况
         *  1.啥也没有
         *      主要:新增wxuser数据,跳转到绑定页面
         *  2.啥都有,直接跳转首页
         *  3.感觉有又感觉没有直接跳转绑定页面
         */
        //处理第一种情况
        //通过
        String openid = wechartTokenDto.getOpenid();
        WxUser dbWxUser = wxUserChatService.findByOpenId(openid);
        //String bindUrl="http://127.0.0.1:8081/binder.html";
        String bindUrl = "http://bugtracker.itsource.cn:8081/binder.html";
        //判断user
        if(dbWxUser==null){
            //copy对象
            WxUser wxUser = BeanUtil.copyProperties(wechartUserInfoDto, WxUser.class);
            //新增对象
            wxUserChatService.saveOrUpdate(wxUser);
            //跳转绑定页面并且携带openid
            return "redirect:"+bindUrl+"?openid="+openid;
        }
        //处理第二种情况什么都有假设
        //获取userid
        Long userId = dbWxUser.getUserId();
        if(userId != null){
            //获取user对象
            User user1 = userMapper.selectByPrimaryKey(userId);
            if(user1!=null && StringUtils.isNotBlank(user1.getPassword())){
                //准备存redis
                LoginInfo loginInfo = BeanUtil.copyProperties(user1, LoginInfo.class);
                String token = IdUtil.fastSimpleUUID();
                loginInfo.setUserId(userId);
                redisService.setStringKeyAndValue(token,loginInfo,30);
                //跳转首页
                return "redirect:http://bugtracker.itsource.cn:8081/index.html"+"?username="+user1.getUsername()+
                        "&email="+user1.getEmail()+"&phone="+user1.getPhone()+"&token="+token;
            }
        }
        //第三种直接跳转绑定页面
        return "redirect:"+bindUrl+"?openid="+openid;
    }

    @Override
    public JsonResult binder(BindDto bindDto) {
        /**
         * 通过手机号查询分情况
         * 1.user表没有数据
         *  新增user表,把自增的id设置wxuser表(通过openid去匹配)
         * 2.user表有数据
         *  把user表的id设置到wxuser表的外键上面
         *
         */
        //判断验证码
        //验证码是否过期
        String keyStringValue = redisService.getKeyStringValue(bindDto.getPhone());
        String code = bindDto.getCode();
        //验证码是否过期
        if(StringUtils.isBlank(keyStringValue)){
            throw new BusinessException("验证吗过期");
        }
        //验证验证码
        if(!StringUtils.equals(code,keyStringValue)){
            throw new BusinessException("验证码不匹配");
        }
        //查询用户
        User byPhone = userMapper.selectPhone(bindDto.getPhone());
        Long userId=null;
        User user1 = null;
        //如果user为空
        if(byPhone==null){
            User user = new User();
            //准备新增
            user.setPhone(bindDto.getPhone());
            //密码写死
            user.setPassword("123456");
            //加密密码
            user.initMD5();
            //新增
            userMapper.insertSelective(user);
            //获取自增id
            userId = user.getId();
            user1=user;
        }else {
            userId=byPhone.getId();
            user1=byPhone;
        }
        //查微信数据
        WxUser wxUser = wxUserMapper.findByOpenId(bindDto.getOpenid());
        //设置userId
        wxUser.setUserId(userId);
        //更新wx表
        wxUserMapper.updateByPrimaryKeySelective(wxUser);
        //4.把登录数据存到redis里面
        LoginInfo loginInfo = BeanUtil.copyProperties(user1, LoginInfo.class);
        String token = IdUtil.fastSimpleUUID();
        loginInfo.setUserId(userId);
        redisService.setStringKeyAndValue(token,loginInfo,30);

        //5.封装LoginVo对象
        LoginVo loginVo = BeanUtil.copyProperties(user1, LoginVo.class);
        loginVo.setToken(token);
        return JsonResult.createSuccess(loginVo);
    }
}
